package com.mall.order.services;

import com.alibaba.fastjson.JSON;
import com.mall.order.OrderCoreService;
import com.mall.order.biz.TransOutboundInvoker;
import com.mall.order.biz.context.AbsTransHandlerContext;
import com.mall.order.biz.factory.OrderProcessPipelineFactory;
import com.mall.order.constant.OrderRetCode;
import com.mall.order.constants.OrderConstants;
import com.mall.order.dal.entitys.Order;
import com.mall.order.dal.entitys.OrderItem;
import com.mall.order.dal.entitys.Stock;
import com.mall.order.dal.persistence.OrderItemMapper;
import com.mall.order.dal.persistence.OrderMapper;
import com.mall.order.dal.persistence.OrderShippingMapper;
import com.mall.order.dal.persistence.StockMapper;
import com.mall.order.dto.*;
import com.mall.order.utils.ExceptionProcessorUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * ciggar
 * create-date: 2019/7/30-上午10:05
 */
@Slf4j
@Service(cluster = "failfast")
public class OrderCoreServiceImpl implements OrderCoreService {

    @Autowired
    OrderMapper orderMapper;

    @Autowired
    OrderItemMapper orderItemMapper;

    @Autowired
    OrderShippingMapper orderShippingMapper;

    @Autowired
    OrderProcessPipelineFactory orderProcessPipelineFactory;

    @Autowired
    StockMapper stockMapper;


    /**
     * 创建订单的处理流程
     *
     * @param request
     * @return
     */
    @Override
    public CreateOrderResponse createOrder(CreateOrderRequest request) {
        CreateOrderResponse response = new CreateOrderResponse();
        try {
            //创建pipeline对象
            TransOutboundInvoker invoker = orderProcessPipelineFactory.build(request);

            //启动pipeline
            invoker.start(); //启动流程（pipeline来处理）

            //获取处理结果
            AbsTransHandlerContext context = invoker.getContext();

            //把处理结果转换为response
            response = (CreateOrderResponse) context.getConvert().convertCtx2Respond(context);
        } catch (Exception e) {
            log.error("OrderCoreServiceImpl.createOrder Occur Exception :" + e);
            ExceptionProcessorUtils.wrapperHandlerException(response, e);
        }
        return response;
    }

    @Override
    public CancelOrderResponse cancelOrder(CancelOrderRequest request) {

        CancelOrderResponse cancelOrderResponse = new CancelOrderResponse();


        Order order = new Order();
        order.setOrderId(request.getOrderId());
        order.setStatus(OrderConstants.ORDER_STATUS_TRANSACTION_CANCEL);
        order.setCloseTime(new Date());

        try {
            request.requestCheck();
            log.info("修改訂單狀態 order:{}", JSON.toJSONString(order));
            // TODO 订单取消之后，其锁定库存应该被恢复

            //order表  修改状态 status 状态 为已取消
            int num = orderMapper.updateByPrimaryKeySelective(order);
            log.info("cancelOrder,effect Row:" + num);


            //修改订单关闭时间
            Order orderClonseTime = new Order();
            orderClonseTime.setCloseTime(new Date());
            Example example3 = new Example(Order.class);
            example3.createCriteria().andEqualTo("orderId", order.getOrderId());
            orderMapper.updateByExampleSelective(orderClonseTime, example3);

            //修改订单商品关联表
            OrderItem orderItemStatus = new OrderItem();
            orderItemStatus.setStatus(3);
            Example orderItemExample = new Example(OrderItem.class);
            orderItemExample.createCriteria().andEqualTo("orderId", order.getOrderId());
            orderItemMapper.updateByExampleSelective(orderItemStatus, orderItemExample);


            //修改商品库存表
            //查询该商品购买数量list
            Example goodsIdExample = new Example(OrderItem.class);
            goodsIdExample.createCriteria().andEqualTo("orderId", order.getOrderId());
            List<OrderItem> orderItemList = orderItemMapper.selectByExample(goodsIdExample);

            //遍历orderItemList中的 商品id 在库存表中找到锁定库存和库存的数量
            //修改

            for (OrderItem orderItem : orderItemList) {
                //一个订单所购买的所有商品的id
                Stock stock = stockMapper.selectStock(orderItem.getItemId());

                //并在锁定字段和库存字段修改
                stock.setStockCount(stock.getStockCount() + orderItem.getNum());
                stock.setLockCount(stock.getLockCount() - orderItem.getNum());

                stockMapper.updateStockByItemId(stock);
            }
            cancelOrderResponse.setCode(OrderRetCode.SUCCESS.getCode());
            cancelOrderResponse.setMsg(OrderRetCode.SUCCESS.getMessage());
        } catch (Exception e) {
            log.error("OrderCoreServiceImpl.cancelOrder Occur Exception :" + e);
            ExceptionProcessorUtils.wrapperHandlerException(cancelOrderResponse, e);
        }
        return cancelOrderResponse;
    }

    @Override
    public DeleteOrderResponse deleteOrder(DeleteOrderRequest request) {

        DeleteOrderResponse deleteOrderResponse = new DeleteOrderResponse();

        try {
            request.requestCheck();
            // TODO 这里是否还需要根据订单当前的状态，在删除订单之后做一些恢复工作？
            // 1.

//            updateOrder(3,request.getOrderId());

            deleteOrderWithTransaction(request);
            deleteOrderResponse.setCode(OrderRetCode.SUCCESS.getCode());
            deleteOrderResponse.setMsg(OrderRetCode.SUCCESS.getMessage());
        } catch (Exception e) {
            log.error("OrderCoreServiceImpl.deleteOrder Occur Exception :" + e);
            ExceptionProcessorUtils.wrapperHandlerException(deleteOrderResponse, e);
        }
        return deleteOrderResponse;
    }

    @Override
    public void updateOrder(Integer status, String orderId) {
        Order order = new Order();
        order.setOrderId(orderId);
        order.setStatus(status);
        orderMapper.updateByPrimaryKeySelective(order);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void deleteOrderWithTransaction(DeleteOrderRequest request) {
        orderMapper.deleteByPrimaryKey(request.getOrderId());
        Example example = new Example(Order.class);
        example.createCriteria().andEqualTo("orderId", request.getOrderId());
        orderItemMapper.deleteByExample(example);
        orderShippingMapper.deleteByPrimaryKey(request.getOrderId());
    }

    @Override
    public int checkOrderStatus(Integer id) {
        Example example = new Example(Order.class);
        example.createCriteria().andEqualTo("order_id", id);

        List<Order> orderList = orderMapper.selectByExample(example);
        String orderId = orderList.get(0).getOrderId();

        return Integer.parseInt(orderId);
    }

}
